﻿using System;
using System.Collections;
using System.Net;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightControlStyle.Controls
{
    /// <summary>
    /// 可编辑的ComboBox
    /// </summary>
    public class EditableComboBox : Control
    {
        private Button _boxButton;
        private AutoCompleteBox _autoCompleteBox;

        private bool _isButtonClick;

        /// <summary>
        /// 筛选成员名称
        /// </summary>
        public string FilterMemberPath { get; set; }

        /// <summary>
        /// 显示的文本
        /// </summary>
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        /// <summary>
        /// 选中项
        /// </summary>
        public object SelectedItem
        {
            get { return GetValue(SelectedItemProperty); }
            set
            {
                SetValue(SelectedItemProperty, value);

                if (_autoCompleteBox != null)
                    _autoCompleteBox.SelectedItem = value;
            }
        }

        /// <summary>
        /// 数据集合
        /// </summary>
        public IEnumerable ItemsSource
        {
            get { return (IEnumerable)GetValue(ItemsSourceProperty); }
            set
            {
                SetValue(ItemsSourceProperty, value);

                if (_autoCompleteBox != null)
                    _autoCompleteBox.ItemsSource = value;
            }
        }

        // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(EditableComboBox), new PropertyMetadata(""));

        // Using a DependencyProperty as the backing store for SelectedItem.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(EditableComboBox), new PropertyMetadata(null));

        // Using a DependencyProperty as the backing store for ItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(EditableComboBox),
                new PropertyMetadata(null));

        /// <summary>
        /// 构造函数
        /// </summary>
        public EditableComboBox()
        {
            DefaultStyleKey = typeof(EditableComboBox);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _boxButton = GetTemplateChild("XDropDownButton") as Button;
            _autoCompleteBox = GetTemplateChild("XAutoCompleteBox") as AutoCompleteBox;

            if (_boxButton != null)
            {
                _boxButton.Click += OnBoxButton_Click;
            }

            if (_autoCompleteBox != null)
            {
                if (ItemsSource != null)
                {
                    _autoCompleteBox.ItemsSource = ItemsSource;
                    _autoCompleteBox.SelectedItem = SelectedItem;
                }
                _autoCompleteBox.ItemFilter = (prefix, item) =>
                {
                    if (_isButtonClick || string.IsNullOrEmpty(prefix))
                        return true;

                    if (item == null)
                        return false;

                    string proValue = GetPropertyValue(item, FilterMemberPath);
                    return proValue.ToLower().Contains(prefix.ToLower());
                };

                _autoCompleteBox.TextChanged += OnAutoCompleteBox_TextChanged;
                _autoCompleteBox.DropDownOpened += OnAutoCompleteBox_DropDownOpened;
            }
        }

        /// <summary>
        /// 点击按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnBoxButton_Click(object sender, RoutedEventArgs e)
        {
            if (_autoCompleteBox == null)
                return;

            _isButtonClick = true;
            _autoCompleteBox.SelectedItem = _autoCompleteBox.Text;
            _autoCompleteBox.IsDropDownOpen = !_autoCompleteBox.IsDropDownOpen;
        }

        /// <summary>
        /// 显示文本发生变化时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnAutoCompleteBox_TextChanged(object sender, RoutedEventArgs e)
        {
            Text = _autoCompleteBox.Text;
        }

        /// <summary>
        /// 下拉项打开后触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnAutoCompleteBox_DropDownOpened(object sender, RoutedPropertyChangedEventArgs<bool> e)
        {
            _isButtonClick = false;
        }

        /// <summary>
        /// 获取object对象属性值
        /// </summary>
        /// <returns></returns>
        public static string GetPropertyValue(object obj, string propertyName)
        {
            if (obj == null)
                return string.Empty;

            Type type = obj.GetType();
            PropertyInfo proInfo = type.GetProperty(propertyName);
            if (proInfo == null)
                return string.Empty;

            object objVal = proInfo.GetValue(obj, null);
            if (objVal == null)
                return string.Empty;

            return objVal.ToString();
        }
    }
}
